package com.xianggu.spring.spi.demo;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceConfigurationError;

public class SpiLoader {

    /**
     * 加载 SPI 实现类
     *
     * @param serviceInterface 服务接口
     * @param classLoader       类加载器
     * @return 服务实现类的实例列表
     */
    public static <T> List<T> load(Class<T> serviceInterface, ClassLoader classLoader) {
        String fileName = "META-INF/spring.factories";
        List<T> implementations = new ArrayList<>();

        try (InputStream inputStream = classLoader.getResourceAsStream(fileName);
             BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
            String line;
            while ((line = reader.readLine()) != null) {
                line = line.trim();
                if (!line.isEmpty() && !line.startsWith("#")) { // 忽略空行和注释
                    Class<?> clazz = Class.forName(line, false, classLoader);
                    if (serviceInterface.isAssignableFrom(clazz)) {
                        T instance = (T) clazz.getDeclaredConstructor().newInstance();
                        implementations.add(instance);
                    } else {
                        throw new ServiceConfigurationError("Provider " + line + " does not implement " + serviceInterface.getName());
                    }
                }
            }
        } catch (Exception e) {
            throw new ServiceConfigurationError("Failed to load SPI implementations for " + serviceInterface.getName(), e);
        }

        return implementations;
    }

    /**
     * 使用默认类加载器加载 SPI 实现类
     */
    public static <T> List<T> load(Class<T> serviceInterface) {
        return load(serviceInterface, Thread.currentThread().getContextClassLoader());
    }
}